#ifndef UTILITY_TR31_H_
#define UTILITY_TR31_H_

#include <stdint.h>

#define TR31_ENCRYPTED_BLOCK_BCD_MAX    (280 + 8)
#define TR31_HEAD_LEN                   (16 + 8)
#define MAC_LEN                         4

#define TR31_LEN_RSA            ( TR31_HEAD_LEN + 2 * (2 + RSA_KEY_LEN + 6 + 4))
#define TR31_LEN_DES            ( TR31_HEAD_LEN + 2 * (2 + DES3_KEY_LEN + 6 + 4))
#define TR31_LEN_DUKPT          ( TR31_HEAD_LEN + 2 * (2 + DES3_KEY_LEN + DUKPT_KSN_LEN + 4 + 4))

/*
 * TR-31 CBC MAC Key Block
 * -----------------------------------------------------------------------
 * | header | header opt | length | Key | KSN(Condition) |Padding | MAC |
 * -----------------------------------------------------------------------
 */

typedef struct {
        uint8_t ver_id;         /* Key Block Version ID --- 'A'(0x41) */
        uint8_t length[4];      /* Key Block Length, including Header + DATA + MAC */
        uint8_t usage[2];       /* Key Usage */
        uint8_t algorithm;      /* The approved algorithm to be used by the protected key */
        uint8_t mode;           /* the operation the protected key can perform */
        uint8_t ver_num[2];     /* Key Version Number */
        uint8_t export;         /* Defines the protected key's exportablility */
        uint8_t option_nr[2];   /* Numbers of optional blocks */
        uint8_t reserv[2];      /* Reserved for future use */
}tr31_kbh_t;


typedef struct{
        uint8_t *key;                   /* output key pointer */
        uint16_t keylen;                /*keylen*/
        uint8_t fid;                    /*filed ID*/
        uint8_t gid;                    /*group ID*/
        uint8_t usage[2];               /* Key Usage */
        uint8_t algorithm;              /* The approved algorithm to be used by the protected key */
        uint8_t mode;                   /* the operation the protected key can perform */
        uint8_t ver_num[2];             /* Key Version Number */
        uint8_t export;                 /* Defines the protected key's exportablility */
        uint8_t ksn[10];                /* Key Serial Number */
        uint8_t reserv[3];              /* Reserved for future use */
}tr31_key_t;

#define KBH_VERID               0x41
#define DUKPT_KSN_LEN           10

/*      key usage (support only as below )*/
#define KEY_USAGE(usage)        (((usage)[0] << 8) | (usage)[1])

#define KEY_USAGE_BDK           0x4230          /* B0:KT_BDK BASE Derivation Key */
#define KEY_USAGE_PRI           0x4430          /* D0:KT_PRI  */
#define KEY_USAGE_MST           0x4B30          /* K0:KT_MST */
#define KEY_USAGE_MAC           0x4D30          /* M0:KT_MAC */
#define KEY_USAGE_PIN           0x5030          /* P0:KT_PIN */
#define KEY_USAGE_MAG           0x4330          /* C0:KT_MAG */

#define KEY_USAGE_MSKEK			0x5330			/* S0:selftest-masterkey-kek*/
#define KEY_USAGE_TSFK			0x5331			/* S1:selftest-transfer-key*/

#define KEY_USAGEA_BDK          "B0"            /* B0:KT_BDK BASE Derivation Key */
#define KEY_USAGEA_PRI          "D0"            /* D0:KT_PRI  */
#define KEY_USAGEA_MST          "K0"            /* K0:KT_MST */
#define KEY_USAGEA_MAC          "M0"            /* M0:KT_MAC */
#define KEY_USAGEA_PIN          "P0"            /* P0:KT_PIN */
#define KEY_USAGEA_MAG          "C0"            /* C0:KT_MAG */

#define KEY_USAGEA_MSKEK		"S0"			/* S0:selftest-masterkey-kek*/
#define KEY_USAGEA_TSFK			"S1"			/* S1:selftest-transfer-key*/

/* key algorithm (support only as below ) */
#define KEY_ALGORITHM_RSA       0x52            /* 'R':RSA */
#define KEY_ALGORITHM_TDEA      0x54            /* 'T':Triple DEA */

/* key mode of use  (support only as below ) */
#define KEY_USEMODE_MAC         0x43            /* 'C':MAC Calculate (Generate or Verify) */
#define KEY_USEMODE_MST         0x44            /* 'D':KT_MST */
#define KEY_USEMODE_ENCRYPT     0x45            /* 'E':KT_PIN, KT_BDK, KT_MAG */
#define KEY_USEMODE_SIG         0x53            /* 'S':KT_PRI */


/*      Required Key Type (Usage + Algorithm + Mode)    */
#define KT_MST_TYPE             "K0TD"
#define KT_PIN_TYPE             "P0TE"
#define KT_MAC_TYPE             "M0TC"
#define KT_PRI_TYPE             "D0RS"
#define KT_BDK_TYPE             "B0TE"
#define KT_MAG_TYPE             "C0TE"

#define KT_MSKEK_TYPE           "S0TD"
#define KT_TSFK_TYPE            "S1TB"

/*      -----key filed ID ----
        '0':KF_MT
        '1': KF_FIXED
        '2': KF_DUKPT
*/

/* Return Value of tr31block_decode Fuction*/
#define TR31BLK_HERR_VER         -1             /*block header version error*/
#define TR31BLK_HERR_EXP         -2             /*block header Exportability error*/
#define TR31BLK_HERR_USG         -3             /*block header usage error*/
#define TR31BLK_HERR_LEN         -4             /*block header length byte error*/
#define TR31BLK_HERR_OPT         -5             /*block header option error*/

#define TR31BLK_ERR_LEN          -10            /*the Decoded block length error*/
#define TR31BLK_ERR_MAC          -11            /*block MAC error*/
#define TR31BLK_ERR_KLEN         -12            /*block KEY length error*/
#define TR31BLK_ERR_NULL         -13            /*Pointer NULL*/
#define TR31BLK_ERR_KSN          -14            /*KSN error*/

int32_t tr31block_decode(uint8_t * blocks, uint32_t blklen,
            uint8_t * kek, int keklen, uint8_t stylereq[4], tr31_key_t * keyst );

#endif /* UTILITY_TR31_H_ */
